#pragma optimize
#pragma save_binary

#include <net/socket.h>

int WriteLoginData_client(mapping data, buffer buf, int start);
int WriteLoginData(mapping data, buffer buf, int start)
{
	mixed tmp;
	if ((!undefinedp(tmp = data["c"])) && mapp(tmp))
	{
		start = WriteLoginData_client((mapping)tmp, buf, start);
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var c not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["ssints"])) && arrayp(tmp))
	{
		int l_t_0 = sizeof(tmp);
		start += write_buffer_7bitInt(buf, l_t_0, start);
		for (int l_t_1 = 0; l_t_1 < l_t_0; ++l_t_1)
		{
			mixed l_t_2 = tmp[l_t_1];
			if (arrayp(l_t_2))
			{
				int l_t_3 = sizeof(l_t_2);
				start += write_buffer_7bitInt(buf, l_t_3, start);
				for (int l_t_4 = 0; l_t_4 < l_t_3; ++l_t_4)
				{
					mixed l_t_5 = l_t_2[l_t_4];
					if (arrayp(l_t_5))
					{
						int l_t_6 = sizeof(l_t_5);
						start += write_buffer_7bitInt(buf, l_t_6, start);
						for (int l_t_7 = 0; l_t_7 < l_t_6; ++l_t_7)
						{
							mixed l_t_8 = l_t_5[l_t_7];
							if (intp(l_t_8))
							{
								write_buffer_int(buf, (int)l_t_8, start); start += 4;
							}
							else
							{
								LOGERROR(("WriteLoginData Error! var l_t_7 type error! value:%s ", save_variable(l_t_8)));
								return -1;
							}

						}
					}
					else
					{
						LOGERROR(("WriteLoginData Error! var l_t_4 type error! value:%s ", save_variable(l_t_5)));
						return -1;
					}

				}
			}
			else
			{
				LOGERROR(("WriteLoginData Error! var l_t_1 type error! value:%s ", save_variable(l_t_2)));
				return -1;
			}

		}
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var ssints not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["clientmap"])) && mapp(tmp))
	{
		int l_t_11 = sizeof(tmp);
		start += write_buffer_7bitInt(buf, l_t_11, start);
		foreach (mixed l_t_9, mixed l_t_10 in tmp)
		{
			if (mapp(l_t_9))
			{
				start = WriteLoginData_client((mapping)l_t_9, buf, start);
			}
			else
			{
				LOGERROR(("WriteLoginData Error! var l_t_9 type error! value:%s ", save_variable(l_t_9)));
				return -1;
			}

			if (stringp(l_t_10))
			{
				start += write_buffer_string(buf, (string)l_t_10, start);
			}
			else
			{
				LOGERROR(("WriteLoginData Error! var l_t_10 type error! value:%s ", save_variable(l_t_10)));
				return -1;
			}

		}
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var clientmap not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["unit1"])) && intp(tmp))
	{
		write_buffer_int(buf, (int)tmp, start); start += 4;
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var unit1 not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["char1"])) && intp(tmp))
	{
		write_buffer_char(buf, (int)tmp, start); start += 1;
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var char1 not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["uchar1"])) && intp(tmp))
	{
		write_buffer_uchar(buf, (int)tmp, start); start += 1;
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var uchar1 not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["short1"])) && intp(tmp))
	{
		write_buffer_ushort(buf, (int)tmp, start); start += 2;
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var short1 not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["ushort1"])) && intp(tmp))
	{
		write_buffer_ushort(buf, (int)tmp, start); start += 2;
	}
	else
	{
		LOGERROR(("WriteLoginData Error! var ushort1 not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	return start;
}
int WriteLoginData_client(mapping data, buffer buf, int start)
{
	mixed tmp;
	if ((!undefinedp(tmp = data["ip"])) && stringp(tmp))
	{
		start += write_buffer_string(buf, (string)tmp, start);
	}
	else
	{
		LOGERROR(("WriteLoginData_client Error! var ip not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	if ((!undefinedp(tmp = data["valueList"])) && arrayp(tmp))
	{
		int l_t_12 = sizeof(tmp);
		start += write_buffer_7bitInt(buf, l_t_12, start);
		for (int l_t_13 = 0; l_t_13 < l_t_12; ++l_t_13)
		{
			mixed l_t_14 = tmp[l_t_13];
			if (intp(l_t_14))
			{
				write_buffer_int(buf, (int)l_t_14, start); start += 4;
			}
			else
			{
				LOGERROR(("WriteLoginData_client Error! var l_t_13 type error! value:%s ", save_variable(l_t_14)));
				return -1;
			}

		}
	}
	else
	{
		LOGERROR(("WriteLoginData_client Error! var valueList not find or type error! value:%s ", save_variable(tmp)));
		return -1;
	}

	return start;
}
int ReadLoginData_client(mapping data, buffer buf, int start);
int ReadLoginData(mapping data, buffer buf, int start)
{
	mixed tmp;
	tmp = ([]);
	start = ReadLoginData_client(tmp, buf, start);
	data["c"] = (mapping)tmp;

	{
		mixed *l_t_0 = read_buffer_7bitInt(buf, start);
		start += l_t_0[0];
		tmp = allocate(l_t_0[1]);
		data["ssints"] = (mixed *)tmp;
		for (int l_t_1 = 0; l_t_1 < l_t_0[1]; ++l_t_1)
		{
			mixed l_t_2;
			{
				mixed *l_t_3 = read_buffer_7bitInt(buf, start);
				start += l_t_3[0];
				l_t_2 = allocate(l_t_3[1]);
				tmp[l_t_1] = (mixed *)l_t_2;
				for (int l_t_4 = 0; l_t_4 < l_t_3[1]; ++l_t_4)
				{
					mixed l_t_5;
					{
						mixed *l_t_6 = read_buffer_7bitInt(buf, start);
						start += l_t_6[0];
						l_t_5 = allocate(l_t_6[1]);
						l_t_2[l_t_4] = (mixed *)l_t_5;
						for (int l_t_7 = 0; l_t_7 < l_t_6[1]; ++l_t_7)
						{
							mixed l_t_8;
							l_t_8 = read_buffer_int(buf, start);
							start += 4;
							l_t_5[l_t_7] = (int)l_t_8;

						}
					}

				}
			}

		}
	}

	{
		mixed *l_t_9 = read_buffer_7bitInt(buf, start);
		start += l_t_9[0];
		tmp = allocate_mapping(l_t_9[1]);
		data["clientmap"] = (mapping)tmp;
		for (int l_t_10 = 0; l_t_10 < l_t_9[1]; ++l_t_10)
		{
			mixed l_t_11, l_t_12;
			l_t_11 = ([]);
			start = ReadLoginData_client(l_t_11, buf, start);
			l_t_12 = read_buffer_string(buf, start);
			start += l_t_12[0];
			l_t_12 = l_t_12[1];
			tmp[l_t_11] = l_t_12;
		}
	}

	tmp = read_buffer_int(buf, start);
	start += 4;
	data["unit1"] = (int)tmp;

	tmp = read_buffer_char(buf, start);
	start += 1;
	data["char1"] = (int)tmp;

	tmp = read_buffer_uchar(buf, start);
	start += 1;
	data["uchar1"] = (int)tmp;

	tmp = read_buffer_short(buf, start);
	start += 2;
	data["short1"] = (int)tmp;

	tmp = read_buffer_ushort(buf, start);
	start += 2;
	data["ushort1"] = (int)tmp;

	return start;
}

int ReadLoginData_client(mapping data, buffer buf, int start)
{
	mixed tmp;
	tmp = read_buffer_string(buf, start);
	start += tmp[0];
	tmp = tmp[1];
	data["ip"] = (string)tmp;

	{
		mixed *l_t_0 = read_buffer_7bitInt(buf, start);
		start += l_t_0[0];
		tmp = allocate(l_t_0[1]);
		data["valueList"] = (mixed *)tmp;
		for (int l_t_1 = 0; l_t_1 < l_t_0[1]; ++l_t_1)
		{
			mixed l_t_2;
			l_t_2 = read_buffer_int(buf, start);
			start += 4;
			tmp[l_t_1] = (int)l_t_2;
		}
	}

	return start;
}

void test()
{
// 	mixed v;
// 	buffer buf = allocate_buffer(500);
// 	write_buffer_string(buf, "987654321");
// 	v = read_buffer_string(buf);
// 	LOGDEBUG(("%s", efun::save_variable(v)));
// 
// 	buffer buf = allocate_buffer(500);
// 	int v;
// 	int start = 0;
// 	mixed ss;
// 	write_buffer_int(buf, 100, start); start += 4;
// 	write_buffer_float(buf, 200, start); start += 4;
// 	write_buffer_char(buf, -25, start); start += 1;
// 	write_buffer_uchar(buf, 2, start); start += 1;
// 	write_buffer_short(buf, 545, start); start += 2;
// 	write_buffer_ushort(buf, 515, start); start += 2;
// 	write_buffer_string(buf, "wxb", start); start += (2+3);
// 	write_buffer_int(buf, 23423, start); start += 4;

// 	start = 0;
// 	ss = read_buffer_int(buf, start); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_float(buf, start); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_char(buf, start); start += 1;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_uchar(buf, start); start += 1;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_short(buf, start); start += 2;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_ushort(buf, start); start += 2;
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_string(buf, start); start += (2+3);
// 	LOGDEBUG(("%s", efun::save_variable(ss)));
// 
// 	ss = read_buffer_int(buf, start);
// 	LOGDEBUG(("%s", efun::save_variable(ss)));

// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_int(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_float(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_char(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_uchar(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_short(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_ushort(buf, start)))); start += 4;
// 	LOGDEBUG(("%s", efun::save_variable(read_buffer_string(buf, start)))); start += 4;
}

void create()
{
// 	test();
// 	return;

  	int s, error;
  	s = socket_create(STREAM_BINARY, "read_callback", "close_callback");
  	if (s < 0)
  	{
  		LOGERROR(("create socket error %s !", socket_error(s)));
  		return;
  	}
  
  	if ((error = socket_bind(s, 12345)) < 0)
  	{
  		LOGERROR(("socket_bind error %s !", socket_error(error)));
  		socket_close(s);
  		return;
  	}
  
  	// 开始接收
  	if ((error = socket_listen(s, "listen_callback")) < 0)
  	{
  		LOGERROR(("socket_listen error %s !", socket_error(error)));
  		socket_close(s);
  		return;
  	}
  
  	LOGDEBUG(("new socket! s=%d", s));
}

void read_callback(int fd, mixed message)
{
//	mixed *v;
	mapping loginData = ([]);
 	LOGDEBUG(("read_callback:%d type:%s sizeof:%d", fd, typeof(message), sizeof(message)));
	ReadLoginData(loginData, message, 0);
	LOGDEBUG(("loginData:%s", save_variable(loginData)));

	{
		socket_write(fd, message);
	}
	
// 	v = read_buffer_string(message);
// 	LOGDEBUG(("read_callback:%s", v[1]));
// 
// 	socket_write(fd, "123456789");

// 	mixed r;
// 	int start = 0;
// 	mapping loginData = ([]);
//  	int* v = ({0,0,0});
// 	LOGDEBUG(("read_callback:%d", sizeof(message)));
// 	r = read_buffer_7bitInt(message, start); start += r[0];
// 	v[0] = r[1];
// 
// 	r = read_buffer_7bitInt(message, start); start += r[0];
// 	v[1] = r[1];
// 
// 	r = read_buffer_7bitInt(message, start); start += r[0];
// 	v[2] = r[1];
// 	LOGDEBUG(("loginData:%s", save_variable(v)));
//	loginData["ip"] = read_buffer_string()

 	//ReadLoginData_client(loginData, (buffer)message, 0);
 	//LOGDEBUG(("loginData:%s", save_variable(loginData)));
}

void close_callback(int fd)
{
	LOGDEBUG(("close_callback:" + fd));
}

void listen_callback(int fd)
{
	string address;
	int newfd;
	LOGDEBUG(("listen_callback:" + fd));

	newfd = socket_accept(fd, "read_callback", "write_callback");
	if (newfd < 0)
	{
		LOGERROR(("socket:%d socket_accept error:%s!", fd, socket_error(newfd)));
		return;
	}

	address = socket_address(newfd);
	LOGDEBUG(("fd:%d address:%s", newfd, address));
}

/* buffer AllocateBuffer(buffer buf, int current, int size)
// {
// 	int len = sizeof(buf);
// 	if (len < current + size)
// 	{
// 		len *= 2;
// 		if (len < current + size)
// 			len = (current + size) * 2;
// 
// 		buffer newBuf = allocate_buffer(len);
// 		copy_buffer(newBuf, buf);
// 		return newBuf;
// 	}
// 
// 	return buf;
// }
// 
// int WriteLoginData(mapping data, buffer buf, int start)
// {
// 	mixed tmp;
// 	if ((!undefinedp(tmp=data["name"])) && stringp(tmp))
// 	{
// 		start += write_buffer_string(buf, (string)tmp, start);
// 	}
// 	else
// 	{
// 		LOGERROR("WriteLoginData Error! var name not find!");
// 		return -1;
// 	}
// 
// 	if (!undefinedp(tmp = data["value"]) && floatp(tmp))
// 	{
// 		write_buffer_float(buf, (float)tmp, start);
// 		start += 4;
// 	}
// 	else
// 	{
// 		LOGERROR("WriteLoginData Error! var value not find!");
// 		return -1;
// 	}
// 
// 	if (!undefinedp(tmp = data["c"]) && mapp(tmp))
// 	{
// 		start += WriteLoginData_Client((mapping)tmp, buf, start);
// 	}
// 	else
// 	{
// 		LOGERROR("WriteLoginData Error! var c not mapp!");
// 		return -1; // 出错了
// 	}
// 
// 	return start;
// }
// 
// int WriteLoginData_Client(mapping data, buffer buf, int start)
// {
// 	mixed tmp;
// 	if (undefinedp(tmp=data["ip"]))
// 	{
// 		start += write_buffer_string(buf, (string)tmp, start);
// 	}
// 
// 	return start;
// }
// 
// mapping ReadLoginData(buffer buf, int start)
// {
// 
// }
*/